
#import	<stdlib.h>
#import	<libc.h>
#import	<math.h>
#import	<time.h>
#import <sys/time.h>
#import	<appkit/Application.h>
#import	<appkit/Slider.h>
#import	<appkit/Button.h>
#import	<appkit/NXImage.h>
#import	<dpsclient/wraps.h>
#import	"WanderingPolygonViewPart.h"

@implementation WanderingPolygonView
extern float frandom();
extern float randBetween(float a, float b);

-randPoint:(NXPoint *)thePoint;
{
	thePoint->x =randBetween(0, bounds.size.width);
	thePoint->y =randBetween(0, bounds.size.height);
	return self;
}

-randMovement:(NXPoint *)thePoint;
{
	thePoint->x =randBetween(-3,3);
	thePoint->y =randBetween(-3, 3);
	return self;
}

-reset;
{
	int x;
	for (x=0; x<NUMPOINTS;x++) {
		[self randPoint:&p[x]];
		[self randMovement:&m[x]];
	}
	NUMPOINTS = floor(randBetween(MINPOINTS, MAXPOINTS));
	return self;
}

- ( const char * ) windowTitle
{
	return ( const char * ) "Wandering Polygon";
}

/**********************************************************************/

- newWindow
{
	[self reset];
	return self;
}

/**********************************************************************/ 

- initFrame : ( const NXRect * ) frameRect
{
	[ super initFrame : frameRect ];
	[ self setOpaque : YES ];	
	[self reset];
	r=0;
	g=0;
	b=0;
	return self;
}

/**********************************************************************/

- sizeTo : ( NXCoord ) width : ( NXCoord ) height
{
	[ super sizeTo : width : height ];
	
	[ self reset ];
	
	return self;
}

/**********************************************************************/

- drawSelf : ( NXRect * ) rects : ( int ) count
{
	if ( !rects || !count )
		return self;
		
	PSsetgray( NX_BLACK );
	
	NXRectFill( rects );
	steps = 0;
	return self;
}


/**********************************************************************/
void NXPutPointInRect(NXPoint *aPoint, const NXRect *aRect, NXCoord inset)
{
	NXRect bRect;
	bRect = *aRect;
  
	NXInsetRect(&bRect, inset, inset);

	if (aPoint->x  < bRect.origin.x)        aPoint->x = bRect.origin.x;
	if (aPoint->y < bRect.origin.y) aPoint->y = bRect.origin.y;

	if (aPoint->y > bRect.origin.y+bRect.size.height)
		aPoint->y = bRect.origin.y+bRect.size.height;

	if (aPoint->x > bRect.origin.x+bRect.size.width)
		aPoint->x = bRect.origin.x+bRect.size.width;

	return;
}

-incColor;
{
	steps++;
	r = fabs(sin((steps+417)/217.0));
	g = fabs(sin((steps+273)/113.0));
	b = fabs(sin((steps+913)/329.0));
//	printf("%f %f %f \n",r,g,b);
	return self;
}

-incTriangle;
{
	int x;

	for (x=0; x<NUMPOINTS;x++) {
		p[x].x = p[x].x+m[x].x;
		p[x].y = p[x].y+m[x].y;
		if (!NXPointInRect(&p[x], &bounds)) {
			NXPutPointInRect(&p[x],&bounds,1);
			[self randMovement:&m[x]];
		}
	}
	[self incColor];
	return self;
}

-drawTriangle;
{
	int x;
	PSnewpath( );	
	PSsetlinewidth(5.0);
	PSsetlinejoin(2);
	PSsetrgbcolor(1-r,1-g, 1-b);
	PSmoveto(p[0].x,p[0].y);
	for (x=1; x<NUMPOINTS;x++) {
		PSlineto(p[x].x,p[x].y);
	}
	PSlineto(p[0].x,p[0].y);
	PSstroke( );
	return self;
}

-blackTriangle;
{
	int x;
	PSnewpath( );	
	PSsetrgbcolor(0, 0, 0);	
	PSmoveto(p[0].x,p[0].y);
	for (x=1; x<NUMPOINTS;x++) {
		PSlineto(p[x].x,p[x].y);
	}
	PSlineto(p[0].x,p[0].y);
	PSeofill( );
	[self reset];
	return self;
}

- oneStep
{
	int x;
	if (steps ==10000) {
		steps =0;
		for (x=0 ; x<1000 ; x++) {
			[self blackTriangle];
			[self incTriangle];
		}
	}
	[self drawTriangle];
	[self incTriangle];
	return self;
}


/**********************************************************************/

@end
